package com.burgeon.backend.SHOPBACKEND.service.Impl;

import com.burgeon.backend.SHOP.service.SystemService;
import com.burgeon.backend.SHOPBACKEND.entity.Android.EmpBindingRecord;
import com.burgeon.backend.SHOPBACKEND.entity.Employee;
import com.burgeon.backend.SHOPBACKEND.entity.recored.BusinessCardRecord;
import com.burgeon.backend.SHOPBACKEND.mappers.BackendEmployeeMapper;
import com.burgeon.backend.SHOPBACKEND.rest.QuerryEmpData;
import com.burgeon.backend.SHOPBACKEND.rest.QuerryEmpDataByInId;
import com.burgeon.backend.SHOPBACKEND.service.BackendEmployeeService;
import com.burgeon.backend.SHOPBACKEND.service.ex.ErrorDataException;
import com.burgeon.backend.SHOPBACKEND.service.ex.UploadException;
import com.burgeon.backend.Util.ImageSynthesis.ImageSynthesis;
import com.burgeon.backend.WeChat.Wxacode;
import com.burgeon.backend.entity.Info;
import com.burgeon.backend.mappers.AccountMapper;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;

@Service
public class BackendEmployeeServiceImpl implements BackendEmployeeService {
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private BackendEmployeeMapper backendEmployeeMapper;
    @Autowired
    private SystemService systemService;
    @Autowired
    private Wxacode wxacode;
    //名片背景图片
    private final static String BACKGROUND = "//root//code//img//config//mingpianbeijing.png";

    /**
     * 生成名片
     * @param ids
     * @param account
     * @return
     * @throws ErrorDataException
     */
    @Override
    public String createBusinessCard(String[] ids, String account) throws ErrorDataException {
        Info info = GetInfo(account);
        //查询每个id导购信息
        QuerryEmpDataByInId querryEmpDataByInId = new QuerryEmpDataByInId(info.getUrl(), info.getAccount(), info.getPassword());
        ArrayList<Employee> erpData = querryEmpDataByInId.getData(ids);
        if (erpData.size() == 0) {
            throw new ErrorDataException("数据错误");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now = sdf.format(new Date());
        //生成名片记录
        BusinessCardRecord businessCardRecord = new BusinessCardRecord();
        businessCardRecord.setAccount(account);
        businessCardRecord.setCreateTime(now);
        businessCardRecord.setNum(erpData.size());
        backendEmployeeMapper.createEmpBusinessCardRecord(businessCardRecord);
        String gsaveFilePath = "//root//code//img//employeeRecord//" + account + "//" + businessCardRecord.getId() + "//11";

        File gdest = new File(gsaveFilePath);
        if (!gdest.getParentFile().exists()) {
            gdest.getParentFile().mkdirs();
        }
        for (Employee emp : erpData) {

            String head = backendEmployeeMapper.findData(emp.getId(), account);
            //判断是否有头像
            if (null == head) {
                if ("男".equals(emp.getSex())) {
                    head = "//root//code//img//config//headm.png";
                }else {
                    head = "//root//code//img//config//headw.png";
                }
            } else {
                //网路路径转化本地路径
                head = ("//root//code" + head.split("http://lfwdcdn.cloudsmicro.com")[1])
                        .replace("/", "//");
            }
//            判断存在生成二维码
            EmpBindingRecord erpBingingRecord = backendEmployeeMapper.findErpBingingRecord(emp.getId(), account);

            if (null == erpBingingRecord) {
//            生成
                String accessToken = systemService.GetAccesToken(account);
                // String filePath = "D:/code/img/employeeRecord/" + account + "/" + businessCardRecord.getId() + "/" + emp.getId() + ".png";

                String linkImg = wxacode.createEmpRQcode(emp.getId(), accessToken, account);
                EmpBindingRecord empBindingRecord = new EmpBindingRecord();
                empBindingRecord.setUrl(linkImg);
                empBindingRecord.setAccount(account);
                empBindingRecord.setEmpId(emp.getId());
                erpBingingRecord = empBindingRecord;
                backendEmployeeMapper.createErpBingingRecord(empBindingRecord);
            }

            erpBingingRecord.setUrl(("/root/code" + erpBingingRecord.getUrl()
                    .split("http://lfwdcdn.cloudsmicro.com")[1])
                    .replace("/", "//"));
            //生成名片

            ImageSynthesis imageSynthesis = new ImageSynthesis();
            // 构建叠加层
            BufferedImage buffImg = null;

            try {

                buffImg = imageSynthesis.watermark(new File(BACKGROUND), new File(head),
                        new File(erpBingingRecord.getUrl()), emp.getName(), emp.getStore());
            } catch (IOException e) {
                e.printStackTrace();
                System.err.println("生成失败");
                throw new ErrorDataException(e.getMessage());
            }
            // 输出水印图片
            //按记录id存储到文件
            String saveFilePath = "//root//code//img//employeeRecord//" + account + "//" + businessCardRecord.getId() + "//" + emp.getId()+emp.getName() + ".png";
            imageSynthesis.generateWaterFile(buffImg, saveFilePath);

        }
        //压缩文件
        String filePath = "//root//code//img//employeeRecord//" + account + "//" + businessCardRecord.getId() + "/";//需要压缩的文件夹完整路径
        String fileName = businessCardRecord.getId();//需要压缩的文件夹名
        String outPath = "//root//code//img//employeeRecord//" + account + "//zip//" + businessCardRecord.getId() + ".zip";//压缩完成后保存为文件，名字随意

        try {
            File dest = new File(outPath);
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            OutputStream is = new FileOutputStream(outPath);//创建文件
            CheckedOutputStream cos = new CheckedOutputStream(is, new CRC32());//检查输出流,采用CRC32算法，保证文件的一致性
            ZipOutputStream zos = new ZipOutputStream(cos);//创建zip文件的输出流
            zos.setEncoding("GBK");//设置编码，防止中文乱码
            File file = new File(filePath);//需要压缩的文件或文件夹对象
            ZipFile(zos, file, fileName);//压缩文件的具体实现函数
            zos.close();
            cos.close();
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new ErrorDataException(e.getMessage());
        }
        System.out.println("压缩完成");
        //返回压缩文件网址

        String url = "http://lfwdcdn.cloudsmicro.com/img/employeeRecord/" + account + "/zip/" + businessCardRecord.getId() + ".zip";
        backendEmployeeMapper.upEmpBusinessCardRecord(businessCardRecord.getId(), url);
        return url;
    }

    @Override
    @Transactional
    public String uploading(String id, MultipartFile img, String account) throws ErrorDataException {
        if (null == img || img.isEmpty()) {
            System.out.println("文件为空");
            throw new UploadException("文件为空");
        }

        String fileName = img.getOriginalFilename(); //文件名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));// 后缀名

        String filePath = "//root//code//img//employee//" + account + "//"; // 上传后的路径
        fileName = id + suffixName; // 新文件名

        //存入数据库
        String url = "http://lfwd.cloudsmicro.com/img/employee/" + account + "/" + fileName;

        try {
            saveFile(img, fileName, filePath);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ErrorDataException(e.getMessage());
        }
        Integer row = backendEmployeeMapper.upData(id, url, account);
        if (1 != row) {
            backendEmployeeMapper.createData(id, url, account);
        }
        return url;

    }

    @Override
    public List<Employee> listData(String account) {
        Info info = GetInfo(account);
        QuerryEmpData querryEmpData = new QuerryEmpData(info.getUrl(), info.getAccount(), info.getPassword());

        try {
            ArrayList<Employee> data = querryEmpData.getData();

            for (Employee employee : data) {
                employee.setImg(backendEmployeeMapper.findData(employee.getId(), account));
            }
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private void saveFile(MultipartFile multipartFile, String fileName, String filePath) throws Exception {
        File dest = new File(filePath + fileName);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }

        multipartFile.transferTo(dest);

    }

    /**
     * 递归 压缩文件
     *
     * @param zos
     * @param file
     * @param fileName
     * @throws Exception
     */
    public static void ZipFile(ZipOutputStream zos, File file, String fileName) throws Exception {
        if (file.isDirectory()) {
            //创建压缩文件的目录结构
            zos.putNextEntry(new ZipEntry(file.getPath().substring(file.getPath().indexOf(fileName)) + File.separator));

            for (File f : file.listFiles()) {
                ZipFile(zos, f, fileName);
            }
        } else {
            //打印输出正在压缩的文件
            System.out.println("正在压缩文件:" + file.getName());
            //创建压缩文件
            zos.putNextEntry(new ZipEntry(file.getPath().substring(file.getPath().indexOf(fileName))));
            //用字节方式读取源文件
            InputStream is = new FileInputStream(file.getPath());
            //创建一个缓存区
            BufferedInputStream bis = new BufferedInputStream(is);
            //字节数组,每次读取1024个字节
            byte[] b = new byte[1024];
            //循环读取，边读边写
            while (bis.read(b) != -1) {
                zos.write(b);//写入压缩文件
            }
            //关闭流
            bis.close();
            is.close();
        }
    }

    private Info GetInfo(String token) {
        return accountMapper.GetAccData(token);
    }
}
